package com.ccnode.codegenerator.taikaoback.util;

import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.util.StringUtils;

/**
 * 密码安全工具类
 * BCrypt 加密算法
 * 提供密码加密、验证、强度检查等功能
 */
public class PasswordUtil {

    private static final BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder();

    /**
     * 加密密码
     * @param plainPassword 明文密码
     * @return 加密后的密码
     */
    public static String encodePassword(String plainPassword) {
        if (!StringUtils.hasText(plainPassword)) {
            throw new IllegalArgumentException("密码不能为空");
        }
        return passwordEncoder.encode(plainPassword);
    }

    /**
     * 验证密码
     * @param plainPassword 明文密码
     * @param encodedPassword 加密密码
     * @return 验证结果
     */
    public static boolean matches(String plainPassword, String encodedPassword) {
        if (!StringUtils.hasText(plainPassword) || !StringUtils.hasText(encodedPassword)) {
            return false;
        }
        return passwordEncoder.matches(plainPassword, encodedPassword);
    }

    /**
     * 检查密码是否为明文格式
     * @param password 密码
     * @return true-明文密码，false-加密密码
     */
    public static boolean isPlainTextPassword(String password) {
        if (!StringUtils.hasText(password)) {
            return false;
        }
        // BCrypt加密密码通常以$2a$、$2b$、$2y$开头，长度为60字符
        return password.length() < 60 && !password.startsWith("$2a$") && 
               !password.startsWith("$2b$") && !password.startsWith("$2y$");
    }

    /**
     * 检查密码强度
     * @param password 密码
     * @return 密码强度等级：0-弱，1-中等，2-强
     */
    public static int checkPasswordStrength(String password) {
        if (!StringUtils.hasText(password)) {
            return 0;
        }

        int score = 0;
        
        // 长度检查
        if (password.length() >= 8) {
            score++;
        }
        
        // 包含数字
        if (password.matches(".*\\d.*")) {
            score++;
        }
        
        // 包含小写字母
        if (password.matches(".*[a-z].*")) {
            score++;
        }
        
        // 包含大写字母
        if (password.matches(".*[A-Z].*")) {
            score++;
        }
        
        // 包含特殊字符
        if (password.matches(".*[!@#$%^&*()_+\\-=\\[\\]{};':\"\\\\|,.<>\\/?].*")) {
            score++;
        }

        // 转换为强度等级
        if (score <= 2) {
            return 0; // 弱
        } else if (score <= 3) {
            return 1; // 中等
        } else {
            return 2; // 强
        }
    }

    /**
     * 获取密码强度描述
     * @param password 密码
     * @return 强度描述
     */
    public static String getUpwdStrengthDescription(String password) {
        int strength = checkPasswordStrength(password);
        switch (strength) {
            case 0:
                return "弱";
            case 1:
                return "中等";
            case 2:
                return "强";
            default:
                return "未知";
        }
    }

    /**
     * 验证密码是否符合安全要求
     * @param password 密码
     * @return 验证结果
     */
    public static boolean isValidPassword(String password) {
        if (!StringUtils.hasText(password)) {
            return false;
        }
        
        // 最低要求：长度至少8位，包含字母和数字
        return password.length() >= 8 && 
               password.matches(".*[a-zA-Z].*") && 
               password.matches(".*\\d.*");
    }

    /**
     * 获取密码验证失败的原因
     * @param password 密码
     * @return 失败原因，如果密码有效则返回null
     */
    public static String getUpwdValidationError(String password) {
        if (!StringUtils.hasText(password)) {
            return "密码不能为空";
        }
        
        if (password.length() < 8) {
            return "密码长度至少8位";
        }
        
        if (!password.matches(".*[a-zA-Z].*")) {
            return "密码必须包含字母";
        }
        
        if (!password.matches(".*\\d.*")) {
            return "密码必须包含数字";
        }
        
        return null; // 密码有效
    }
}
